﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using TwinCAT.Ads;    // 注意需要导入ADS库来进行连接

namespace PlcUI_test
{
    public static class GlobalVariables
    {
        // 各种焊机的数量，预定义好
        /// <summary>
        /// 独立移动焊机数目
        /// </summary>
        public static int SeparateWelderNum = 16;

        /// <summary>
        /// 集成焊机数目
        /// </summary>
        public static int ConcentratedWelderNum = 24;

        /// <summary>
        /// 总焊机数目
        /// </summary>
        public static int WelderNum = SeparateWelderNum + ConcentratedWelderNum;
    }
    // 先按照师兄写的抄，只重构逻辑


    interface IHanji
    {
        /// <summary>
        /// 开始焊接，对应LED1位0，1起弧
        /// </summary>
        bool H_W_Q_Start { get; }

        /// <summary>
        /// 机器人准备好（打开焊机），对应LED1位1，高有效
        /// </summary>
        bool H_W_Q_RobotReady { get; }

        /// <summary>
        /// 气检，对应LED1位2，高有效
        /// </summary>
        bool H_W_Q_GasCheck { get; }

        /// <summary>
        /// 焊机操作模式：0关机 1两步  2四步  3反复
        /// </summary>
        short H_W_M_OperationMode { get; }

        /// <summary>
        /// 焊机工作模式：0关机 1直流恒流   2支流脉冲  3交流恒流  4交流脉冲  5直流手弧焊
        /// </summary>
        short H_W_M_WorkModel { get; }

        /// <summary>
        /// 高频有无，对应LED2位6  0高频  1提升
        /// </summary>
        bool H_W_Q_ISHighfrequency { get; }

        /// <summary>
        /// 焊枪模式，对应LED2位7  0水冷  1气冷
        /// </summary>
        bool H_W_Q_WeldingGunMode { get; }

        /// <summary>
        /// 给定电流，4-410A，对应LED5和LED6
        /// </summary>
        ushort H_W_D_GivenCurrent { get; }

        /// <summary>
        /// 前气时间，1-999对应0.01-9.99s，对应LED14和LED15
        /// </summary>
        float H_W_D_PreAirTime { get; }

        /// <summary>
        /// 延气时间，1-999对应0.01-9.99s，对应LED16和LED17
        /// </summary>
        float H_W_D_DelayAirTime { get; }

        /// <summary>
        /// 爬升时间，1-100对应0.1-10.0s 对应LED18
        /// </summary>
        float H_W_B_ClimbingTime { get; }

        /// <summary>
        /// 衰减时间，1-150对应0.1-15.0s 对应LED19
        /// </summary>
        float H_W_B_SDecayTime { get; }

        /// <summary>
        /// 脉冲频率，2-200对应0.2-20.0hz，对应LED20
        /// </summary>
        float H_W_B_PulseFrequency { get; }

        /// <summary>
        /// 占空比，1-99,对应LED21
        /// </summary>
        byte H_W_B_DutyCycle { get; }

        /// <summary>
        /// 峰值电流，5-400A，对应LED22和LED23
        /// </summary>
        ushort H_W_D_PeakCurrent { get; }

        /// <summary>
        /// 基值电流，5-400A，对应LED24和LED25 
        /// </summary>
        ushort H_W_D_BaseCurrent { get; }

        /// <summary>
        /// 起弧电流，5-400A，对应LED26和LED27 
        /// </summary>
        ushort H_W_D_ArcingCurrent { get; }

        /// <summary>
        /// 收弧电流，5-400A，对应LED28和LED29
        /// </summary>
        ushort H_W_D_ArcCurrent { get; }

        /// <summary>
        /// 交流频率，40-250hz，对应LED30
        /// </summary>
        byte H_W_B_CommunicationFrequency { get; }

        /// <summary>
        /// 清理比例，90-180对应40-50 ，对应LED31
        /// </summary>
        byte H_W_B_CleaningRatio { get; }

        /// <summary>
        /// 交流偏置，90-180对应40-50 ，对应LED32
        /// </summary>
        byte H_W_B_ACOffset { get; }


        // 读取部分，读取switch变量

        /// <summary>
        /// 通讯状态标志 
        /// </summary>
        bool H_R_I_CommunicationStatus { get; }

        /// <summary>
        /// 引弧成功，高有效，LED1位0
        /// </summary>
        bool H_R_I_ArcIgnitionSuccessful { get; }

        /// <summary>
        /// 焊机是否准备好，高有效，LED1位1
        /// </summary>
        bool H_R_I_ISWeldingMachineReady { get; }

        /// <summary>
        /// 电流有无，高有效，LED1位3
        /// </summary>
        bool H_R_I_ISCurrent { get; }

        /// <summary>
        /// 焊枪开关异常，高有效，LED2位1
        /// </summary>
        bool H_R_I_AbnormalWeldingGunSwitch { get; }

        /// <summary>
        /// 焊机热保护有效，高有效，LED2位2
        /// </summary>
        bool H_R_I_WeldingMachineThermalProtection { get; }

        /// <summary>
        /// 缺水保护，高有效，LED2位3
        /// </summary>
        bool H_R_I_WaterShortageProtection { get; }

        /// <summary>
        /// 实际焊接电压，0-1000对应0-100v，对应LED5和LED6
        /// </summary>
        ushort H_R_D_ActualWeldingVoltage { get; }

        /// <summary>
        /// 实际焊接电流，0-400A,对应LED7和LED8
        /// </summary>
        ushort H_R_D_ActualWeldingCurrent { get; }

    }

    interface IResiji
    {
        /// <summary>
        /// 热丝电源开关，对应LED2位0   0 on  1 off
        /// </summary>
        bool R_W_Q_HotWirePower { get; }

        /// <summary>
        /// 热丝工作模式，对应LED2位1   0直流 1交流
        /// </summary>
        bool R_W_Q_HotWireWorkMode { get; }

        /// <summary>
        /// 热丝频率，20-100hz，对应LED3
        /// </summary>
        byte R_W_B_HotWireFrequency { get; }

        /// <summary>
        /// 目标热丝电流，0-200A，对应LED4
        /// </summary>
        byte R_W_B_HotWireCurrent { get; }

        /// <summary>
        /// 热丝电源热保护，高有效，LED2位4
        /// </summary>
        bool H_R_I_HotWirePowerThermalProtection { get; }

        /// <summary>
        /// 热丝电源通讯保护，高有效，LED2位5
        /// </summary>
        bool H_R_I_HotWirePowerCommunicationProtection { get; }

        /// <summary>
        /// 实际热丝电流，0-20对应0-200A，对应LED9和LED10
        /// </summary>
        ushort R_R_D_HotWirecurrent { get; }
    }

    interface ISongsiji
    {
        /// <summary>
        /// 点动送丝,对应LED2位3，高电平有效，丝检时使用
        /// </summary>
        bool S_W_Q_WireFeedingJog { get; }

        /// <summary>
        /// 点动抽丝,对应LED2位4，高电平有效，丝检时使用
        /// </summary>
        bool S_W_Q_WirePullingJog { get; }

        /// <summary>
        /// 送丝速度,0-70对应0-7m/min，对应LED7
        /// </summary>
        float S_W_B_Wirefeedingspeed { get; }

        /// <summary>
        /// 起弧延迟送丝时间，0-99对应0-9.9s，对应LED8
        /// </summary>
        float S_W_B_ArcInitiationDelayWireFeedingTime { get; }

        /// <summary>
        /// 熄弧滞后送丝时间，0-99对应0-9.9s，对应LED9
        /// </summary>
        float S_W_B_ArcExtinguishingDelayWireFeedingTime { get; }

        /// <summary>
        /// 熄弧回抽长度，0-50mm，对应LED10
        /// </summary>
        byte S_W_B_ArcExtinguishingAndRetractionlength { get; }

        /// <summary>
        /// 点动送丝速度，0-70对应0-7m/min，对应LED11
        /// </summary>
        float S_W_B_JoggingWireFeedingSpeed { get; }

        /// <summary>
        /// 慢送丝速度，0-70对应0-7m/min，对应LED13
        /// </summary>
        float S_W_B_SlowWireFeedingSpeed { get; }

        // 读取部分
        /// <summary>
        /// 送丝速度，0-70对应0-7m/min，对应LED11和LED12
        /// </summary>
        float S_R_D_WireFeedingSpeed { get; }

    }


    /// <summary>
    /// 焊机接口定义，只用来从下位机读状态数据
    /// </summary>
    /// 需要定义的方法
    ///
    interface ITheWelder : IResiji, ISongsiji, IHanji
    {

    }


    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct AOTAI_Resiji : IResiji
    {
        public AOTAI_Resiji(bool inilialize)
        {
            _R_W_Q_HotWirePower = false;
            _R_W_Q_HotWireWorkMode = false;
            _R_W_B_HotWireFrequency = 0;
            _R_W_B_HotWireCurrent = 0;
            _H_R_I_HotWirePowerThermalProtection = false;

            _H_R_I_HotWirePowerCommunicationProtection = false;
            _R_R_D_HotWirecurrent = 0;
        }
        [MarshalAs(UnmanagedType.I1)]
        private bool _R_W_Q_HotWirePower;
        public bool R_W_Q_HotWirePower
        {
            get { return _R_W_Q_HotWirePower; }
            set { _R_W_Q_HotWirePower = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _R_W_Q_HotWireWorkMode;
        public bool R_W_Q_HotWireWorkMode
        {
            get { return _R_W_Q_HotWireWorkMode; }
            set { _R_W_Q_HotWireWorkMode = value; }
        }

        [MarshalAs(UnmanagedType.U1)]
        private byte _R_W_B_HotWireFrequency;
        public byte R_W_B_HotWireFrequency
        {
            get { return _R_W_B_HotWireFrequency; }
            set { _R_W_B_HotWireFrequency = value; }
        }

        [MarshalAs(UnmanagedType.U1)]
        private byte _R_W_B_HotWireCurrent;
        public byte R_W_B_HotWireCurrent
        {
            get { return _R_W_B_HotWireCurrent; }
            set { _R_W_B_HotWireCurrent = value; }
        }

        //读取部分，读取switch变量
        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_HotWirePowerThermalProtection;
        public bool H_R_I_HotWirePowerThermalProtection
        {
            get { return _H_R_I_HotWirePowerThermalProtection; }
            set { _H_R_I_HotWirePowerThermalProtection = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_HotWirePowerCommunicationProtection;
        public bool H_R_I_HotWirePowerCommunicationProtection
        {
            get { return _H_R_I_HotWirePowerCommunicationProtection; }
            set { _H_R_I_HotWirePowerCommunicationProtection = value; }
        }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _R_R_D_HotWirecurrent;
        public ushort R_R_D_HotWirecurrent
        {
            get { return _R_R_D_HotWirecurrent; }
            set { _R_R_D_HotWirecurrent = value; }
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct AOTAI_Songsiji : ISongsiji
    {
        public AOTAI_Songsiji(bool Initialize)
        {
            _S_W_Q_WireFeedingJog = false;
            _S_W_Q_WirePullingJog = false;
            _S_W_B_Wirefeedingspeed = 0;

            _S_W_B_ArcInitiationDelayWireFeedingTime = 0;
            _S_W_B_ArcExtinguishingDelayWireFeedingTime = 0;
            _S_W_B_ArcExtinguishingAndRetractionlength = 0;
            _S_W_B_JoggingWireFeedingSpeed = 0;
            _S_W_B_SlowWireFeedingSpeed = 0;

            _S_R_D_WireFeedingSpeed = 0;
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _S_W_Q_WireFeedingJog;
        public bool S_W_Q_WireFeedingJog
        {
            get { return _S_W_Q_WireFeedingJog; }
            set { _S_W_Q_WireFeedingJog = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _S_W_Q_WirePullingJog;
        public bool S_W_Q_WirePullingJog
        {
            get { return _S_W_Q_WirePullingJog; }
            set { _S_W_Q_WirePullingJog = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_R_D_WireFeedingSpeed;
        public float S_R_D_WireFeedingSpeed
        {
            get { return _S_R_D_WireFeedingSpeed; }
            set { _S_R_D_WireFeedingSpeed = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_ArcInitiationDelayWireFeedingTime;
        public float S_W_B_ArcInitiationDelayWireFeedingTime
        {
            get { return _S_W_B_ArcInitiationDelayWireFeedingTime; }
            set { _S_W_B_ArcInitiationDelayWireFeedingTime = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_ArcExtinguishingDelayWireFeedingTime;
        public float S_W_B_ArcExtinguishingDelayWireFeedingTime
        {
            get { return _S_W_B_ArcExtinguishingDelayWireFeedingTime; }
            set { _S_W_B_ArcExtinguishingDelayWireFeedingTime = value; }
        }

        [MarshalAs(UnmanagedType.U1)]
        private byte _S_W_B_ArcExtinguishingAndRetractionlength;
        public byte S_W_B_ArcExtinguishingAndRetractionlength
        {
            get { return _S_W_B_ArcExtinguishingAndRetractionlength; }
            set { _S_W_B_ArcExtinguishingAndRetractionlength = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_JoggingWireFeedingSpeed;
        public float S_W_B_JoggingWireFeedingSpeed
        {
            get { return _S_W_B_JoggingWireFeedingSpeed; }
            set { _S_W_B_JoggingWireFeedingSpeed = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_SlowWireFeedingSpeed;
        public float S_W_B_SlowWireFeedingSpeed
        {
            get { return _S_W_B_SlowWireFeedingSpeed; }
            set { _S_W_B_SlowWireFeedingSpeed = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_Wirefeedingspeed;
        public float S_W_B_Wirefeedingspeed
        {
            get { return _S_W_B_Wirefeedingspeed; }
            set { _S_W_B_Wirefeedingspeed = value; }
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct AOTAI_Hanji : IHanji
    {
        public AOTAI_Hanji(bool Initialize)
        {
            _H_W_Q_Start = false;
            _H_W_Q_RobotReady = false;
            _H_W_Q_GasCheck = false;
            _H_W_M_OperationMode = 0;
            _H_W_M_WorkModel = 0;

            _H_W_Q_ISHighfrequency = false;
            _H_W_Q_WeldingGunMode = false;
            _H_W_D_GivenCurrent = 0;
            _H_W_D_PreAirTime = 0;
            _H_W_D_DelayAirTime = 0;

            _H_W_B_ClimbingTime = 0;
            _H_W_B_SDecayTime = 0;
            _H_W_B_PulseFrequency = 0;
            _H_W_B_DutyCycle = 0;
            _H_W_D_PeakCurrent = 0;

            _H_W_D_BaseCurrent = 0;
            _H_W_D_ArcingCurrent = 0;
            _H_W_D_ArcCurrent = 0;
            _H_W_B_CommunicationFrequency = 0;
            _H_W_B_CleaningRatio = 0;

            _H_W_B_ACOffset = 0;
            _H_R_I_CommunicationStatus = false;
            _H_R_I_ArcIgnitionSuccessful = false;
            _H_R_I_ISWeldingMachineReady = false;
            _H_R_I_ISCurrent = false;

            _H_R_I_AbnormalWeldingGunSwitch = false;
            _H_R_I_WeldingMachineThermalProtection = false;
            _H_R_I_WaterShortageProtection = false;
            _H_R_D_ActualWeldingVoltage = 0;
            _H_R_D_ActualWeldingCurrent = 0;
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_Start;
        public bool H_W_Q_Start { get { return _H_W_Q_Start; } set { _H_W_Q_Start = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_RobotReady;
        public bool H_W_Q_RobotReady { get { return _H_W_Q_RobotReady; } set { _H_W_Q_RobotReady = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_GasCheck;
        public bool H_W_Q_GasCheck { get { return _H_W_Q_GasCheck; } set { _H_W_Q_GasCheck = value; } }

        [MarshalAs(UnmanagedType.I2)]
        private short _H_W_M_OperationMode;
        public short H_W_M_OperationMode { get { return _H_W_M_OperationMode; } set { _H_W_M_OperationMode = value; } }

        [MarshalAs(UnmanagedType.I2)]
        private short _H_W_M_WorkModel;
        public short H_W_M_WorkModel { get { return _H_W_M_WorkModel; } set { _H_W_M_WorkModel = value; } }



        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_ISHighfrequency;
        public bool H_W_Q_ISHighfrequency { get { return _H_W_Q_ISHighfrequency; } set { _H_W_Q_ISHighfrequency = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_WeldingGunMode;
        public bool H_W_Q_WeldingGunMode { get { return _H_W_Q_WeldingGunMode; } set { _H_W_Q_WeldingGunMode = value; } }


        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_W_D_GivenCurrent;
        public ushort H_W_D_GivenCurrent { get { return _H_W_D_GivenCurrent; } set { _H_W_D_GivenCurrent = value; } }


        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_D_PreAirTime;
        public float H_W_D_PreAirTime { get { return _H_W_D_PreAirTime; } set { _H_W_D_PreAirTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_D_DelayAirTime;
        public float H_W_D_DelayAirTime { get { return _H_W_D_DelayAirTime; } set { _H_W_D_DelayAirTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_B_ClimbingTime;
        public float H_W_B_ClimbingTime { get { return _H_W_B_ClimbingTime; } set { _H_W_B_ClimbingTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_B_SDecayTime;
        public float H_W_B_SDecayTime { get { return _H_W_B_SDecayTime; } set { _H_W_B_SDecayTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_B_PulseFrequency;
        public float H_W_B_PulseFrequency { get { return _H_W_B_PulseFrequency; } set { _H_W_B_PulseFrequency = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_DutyCycle;
        public byte H_W_B_DutyCycle { get { return _H_W_B_DutyCycle; } set { _H_W_B_DutyCycle = value; } }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_W_D_PeakCurrent;
        public ushort H_W_D_PeakCurrent { get { return _H_W_D_PeakCurrent; } set { _H_W_D_PeakCurrent = value; } }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_W_D_BaseCurrent;
        public ushort H_W_D_BaseCurrent { get { return _H_W_D_BaseCurrent; } set { _H_W_D_BaseCurrent = value; } }

        [MarshalAs(UnmanagedType.U2)]
        public ushort _H_W_D_ArcingCurrent;
        public ushort H_W_D_ArcingCurrent { get { return _H_W_D_ArcingCurrent; } set { _H_W_D_ArcingCurrent = value; } }

        [MarshalAs(UnmanagedType.U2)]
        public ushort _H_W_D_ArcCurrent;
        public ushort H_W_D_ArcCurrent { get { return _H_W_D_ArcCurrent; } set { _H_W_D_ArcCurrent = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_CommunicationFrequency;
        public byte H_W_B_CommunicationFrequency { get { return _H_W_B_CommunicationFrequency; } set { _H_W_B_CommunicationFrequency = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_CleaningRatio;
        public byte H_W_B_CleaningRatio { get { return _H_W_B_CleaningRatio; } set { _H_W_B_CleaningRatio = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_ACOffset;
        public byte H_W_B_ACOffset { get { return _H_W_B_ACOffset; } set { _H_W_B_ACOffset = value; } }



        // 读取部分 读switch变量
        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_CommunicationStatus;
        public bool H_R_I_CommunicationStatus { get { return _H_R_I_CommunicationStatus; } set { _H_R_I_CommunicationStatus = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_ArcIgnitionSuccessful;
        public bool H_R_I_ArcIgnitionSuccessful { get { return _H_R_I_ArcIgnitionSuccessful; } set { _H_R_I_ArcIgnitionSuccessful = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_ISWeldingMachineReady;
        public bool H_R_I_ISWeldingMachineReady { get { return _H_R_I_ISWeldingMachineReady; } set { _H_R_I_ISWeldingMachineReady = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_ISCurrent;
        public bool H_R_I_ISCurrent
        {
            get { return _H_R_I_ISCurrent; }
            set { _H_R_I_ISCurrent = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_AbnormalWeldingGunSwitch;
        public bool H_R_I_AbnormalWeldingGunSwitch
        {
            get { return _H_R_I_AbnormalWeldingGunSwitch; }
            set { _H_R_I_AbnormalWeldingGunSwitch = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_WeldingMachineThermalProtection;
        public bool H_R_I_WeldingMachineThermalProtection
        {
            get { return _H_R_I_WeldingMachineThermalProtection; }
            set { _H_R_I_WeldingMachineThermalProtection = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_WaterShortageProtection;
        public bool H_R_I_WaterShortageProtection
        {
            get { return _H_R_I_WaterShortageProtection; }
            set { _H_R_I_WaterShortageProtection = value; }
        }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_R_D_ActualWeldingVoltage;
        public ushort H_R_D_ActualWeldingVoltage
        {
            get { return _H_R_D_ActualWeldingVoltage; }
            set { _H_R_D_ActualWeldingVoltage = value; }
        }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_R_D_ActualWeldingCurrent;
        public ushort H_R_D_ActualWeldingCurrent
        {
            get { return _H_R_D_ActualWeldingCurrent; }
            set { _H_R_D_ActualWeldingCurrent = value; }
        }
    }








    /// <summary>
    /// 单个焊机状态数据传递结构体
    /// </summary>
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct thePLCWelderStatus : ITheWelder
    {

        #region 焊机数据类型
        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_Start;
        public bool H_W_Q_Start { get { return _H_W_Q_Start; } set { _H_W_Q_Start = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_RobotReady;
        public bool H_W_Q_RobotReady { get { return _H_W_Q_RobotReady; } set { _H_W_Q_RobotReady = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_GasCheck;
        public bool H_W_Q_GasCheck { get { return _H_W_Q_GasCheck; } set { _H_W_Q_GasCheck = value; } }

        [MarshalAs(UnmanagedType.I2)]
        private short _H_W_M_OperationMode;
        public short H_W_M_OperationMode { get { return _H_W_M_OperationMode; } set { _H_W_M_OperationMode = value; } }

        [MarshalAs(UnmanagedType.I2)]
        private short _H_W_M_WorkModel;
        public short H_W_M_WorkModel { get { return _H_W_M_WorkModel; } set { _H_W_M_WorkModel = value; } }



        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_ISHighfrequency;
        public bool H_W_Q_ISHighfrequency { get { return _H_W_Q_ISHighfrequency; } set { _H_W_Q_ISHighfrequency = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_W_Q_WeldingGunMode;
        public bool H_W_Q_WeldingGunMode { get { return _H_W_Q_WeldingGunMode; } set { _H_W_Q_WeldingGunMode = value; } }


        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_W_D_GivenCurrent;
        public ushort H_W_D_GivenCurrent { get { return _H_W_D_GivenCurrent; } set { _H_W_D_GivenCurrent = value; } }


        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_D_PreAirTime;
        public float H_W_D_PreAirTime { get { return _H_W_D_PreAirTime; } set { _H_W_D_PreAirTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_D_DelayAirTime;
        public float H_W_D_DelayAirTime { get { return _H_W_D_DelayAirTime; } set { _H_W_D_DelayAirTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_B_ClimbingTime;
        public float H_W_B_ClimbingTime { get { return _H_W_B_ClimbingTime; } set { _H_W_B_ClimbingTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_B_SDecayTime;
        public float H_W_B_SDecayTime { get { return _H_W_B_SDecayTime; } set { _H_W_B_SDecayTime = value; } }

        [MarshalAs(UnmanagedType.R4)]
        private float _H_W_B_PulseFrequency;
        public float H_W_B_PulseFrequency { get { return _H_W_B_PulseFrequency; } set { _H_W_B_PulseFrequency = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_DutyCycle;
        public byte H_W_B_DutyCycle { get { return _H_W_B_DutyCycle; } set { _H_W_B_DutyCycle = value; } }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_W_D_PeakCurrent;
        public ushort H_W_D_PeakCurrent { get { return _H_W_D_PeakCurrent; } set { _H_W_D_PeakCurrent = value; } }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_W_D_BaseCurrent;
        public ushort H_W_D_BaseCurrent { get { return _H_W_D_BaseCurrent; } set { _H_W_D_BaseCurrent = value; } }

        [MarshalAs(UnmanagedType.U2)]
        public ushort _H_W_D_ArcingCurrent;
        public ushort H_W_D_ArcingCurrent { get { return _H_W_D_ArcingCurrent; } set { _H_W_D_ArcingCurrent = value; } }

        [MarshalAs(UnmanagedType.U2)]
        public ushort _H_W_D_ArcCurrent;
        public ushort H_W_D_ArcCurrent { get { return _H_W_D_ArcCurrent; } set { _H_W_D_ArcCurrent = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_CommunicationFrequency;
        public byte H_W_B_CommunicationFrequency { get { return _H_W_B_CommunicationFrequency; } set { _H_W_B_CommunicationFrequency = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_CleaningRatio;
        public byte H_W_B_CleaningRatio { get { return _H_W_B_CleaningRatio; } set { _H_W_B_CleaningRatio = value; } }

        [MarshalAs(UnmanagedType.U1)]
        private byte _H_W_B_ACOffset;
        public byte H_W_B_ACOffset { get { return _H_W_B_ACOffset; } set { _H_W_B_ACOffset = value; } }



        // 读取部分 读switch变量
        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_CommunicationStatus;
        public bool H_R_I_CommunicationStatus { get { return _H_R_I_CommunicationStatus; } set { _H_R_I_CommunicationStatus = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_ArcIgnitionSuccessful;
        public bool H_R_I_ArcIgnitionSuccessful { get { return _H_R_I_ArcIgnitionSuccessful; } set { _H_R_I_ArcIgnitionSuccessful = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_ISWeldingMachineReady;
        public bool H_R_I_ISWeldingMachineReady { get { return _H_R_I_ISWeldingMachineReady; } set { _H_R_I_ISWeldingMachineReady = value; } }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_ISCurrent;
        public bool H_R_I_ISCurrent
        {
            get { return _H_R_I_ISCurrent; }
            set { _H_R_I_ISCurrent = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_AbnormalWeldingGunSwitch;
        public bool H_R_I_AbnormalWeldingGunSwitch
        {
            get { return _H_R_I_AbnormalWeldingGunSwitch; }
            set { _H_R_I_AbnormalWeldingGunSwitch = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_WeldingMachineThermalProtection;
        public bool H_R_I_WeldingMachineThermalProtection
        {
            get { return _H_R_I_WeldingMachineThermalProtection; }
            set { _H_R_I_WeldingMachineThermalProtection = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_WaterShortageProtection;
        public bool H_R_I_WaterShortageProtection
        {
            get { return _H_R_I_WaterShortageProtection; }
            set { _H_R_I_WaterShortageProtection = value; }
        }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_R_D_ActualWeldingVoltage;
        public ushort H_R_D_ActualWeldingVoltage
        {
            get { return _H_R_D_ActualWeldingVoltage; }
            set { _H_R_D_ActualWeldingVoltage = value; }
        }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _H_R_D_ActualWeldingCurrent;
        public ushort H_R_D_ActualWeldingCurrent
        {
            get { return _H_R_D_ActualWeldingCurrent; }
            set { _H_R_D_ActualWeldingCurrent = value; }
        }

        #endregion


        #region 热丝机数据类型

        [MarshalAs(UnmanagedType.I1)]
        private bool _R_W_Q_HotWirePower;
        public bool R_W_Q_HotWirePower
        {
            get { return _R_W_Q_HotWirePower; }
            set { _R_W_Q_HotWirePower = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _R_W_Q_HotWireWorkMode;
        public bool R_W_Q_HotWireWorkMode
        {
            get { return _R_W_Q_HotWireWorkMode; }
            set { _R_W_Q_HotWireWorkMode = value; }
        }

        [MarshalAs(UnmanagedType.U1)]
        private byte _R_W_B_HotWireFrequency;
        public byte R_W_B_HotWireFrequency
        {
            get { return _R_W_B_HotWireFrequency; }
            set { _R_W_B_HotWireFrequency = value; }
        }

        [MarshalAs(UnmanagedType.U1)]
        private byte _R_W_B_HotWireCurrent;
        public byte R_W_B_HotWireCurrent
        {
            get { return _R_W_B_HotWireCurrent; }
            set { _R_W_B_HotWireCurrent = value; }
        }

        //读取部分，读取switch变量
        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_HotWirePowerThermalProtection;
        public bool H_R_I_HotWirePowerThermalProtection
        {
            get { return _H_R_I_HotWirePowerThermalProtection; }
            set { _H_R_I_HotWirePowerThermalProtection = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _H_R_I_HotWirePowerCommunicationProtection;
        public bool H_R_I_HotWirePowerCommunicationProtection
        {
            get { return _H_R_I_HotWirePowerCommunicationProtection; }
            set { _H_R_I_HotWirePowerCommunicationProtection = value; }
        }

        [MarshalAs(UnmanagedType.U2)]
        private ushort _R_R_D_HotWirecurrent;
        public ushort R_R_D_HotWirecurrent
        {
            get { return _R_R_D_HotWirecurrent; }
            set { _R_R_D_HotWirecurrent = value; }
        }
        #endregion

        #region 送丝机数据类型
        [MarshalAs(UnmanagedType.I1)]
        private bool _S_W_Q_WireFeedingJog;
        public bool S_W_Q_WireFeedingJog
        {
            get { return _S_W_Q_WireFeedingJog; }
            set { _S_W_Q_WireFeedingJog = value; }
        }

        [MarshalAs(UnmanagedType.I1)]
        private bool _S_W_Q_WirePullingJog;
        public bool S_W_Q_WirePullingJog
        {
            get { return _S_W_Q_WirePullingJog; }
            set { _S_W_Q_WirePullingJog = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_R_D_WireFeedingSpeed;
        public float S_R_D_WireFeedingSpeed
        {
            get { return _S_R_D_WireFeedingSpeed; }
            set { _S_R_D_WireFeedingSpeed = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_ArcInitiationDelayWireFeedingTime;
        public float S_W_B_ArcInitiationDelayWireFeedingTime
        {
            get { return _S_W_B_ArcInitiationDelayWireFeedingTime; }
            set { _S_W_B_ArcInitiationDelayWireFeedingTime = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_ArcExtinguishingDelayWireFeedingTime;
        public float S_W_B_ArcExtinguishingDelayWireFeedingTime
        {
            get { return _S_W_B_ArcExtinguishingDelayWireFeedingTime; }
            set { _S_W_B_ArcExtinguishingDelayWireFeedingTime = value; }
        }

        [MarshalAs(UnmanagedType.U1)]
        private byte _S_W_B_ArcExtinguishingAndRetractionlength;
        public byte S_W_B_ArcExtinguishingAndRetractionlength
        {
            get { return _S_W_B_ArcExtinguishingAndRetractionlength; }
            set { _S_W_B_ArcExtinguishingAndRetractionlength = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_JoggingWireFeedingSpeed;
        public float S_W_B_JoggingWireFeedingSpeed
        {
            get { return _S_W_B_JoggingWireFeedingSpeed; }
            set { _S_W_B_JoggingWireFeedingSpeed = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_SlowWireFeedingSpeed;
        public float S_W_B_SlowWireFeedingSpeed
        {
            get { return _S_W_B_SlowWireFeedingSpeed; }
            set { _S_W_B_SlowWireFeedingSpeed = value; }
        }

        [MarshalAs(UnmanagedType.R4)]
        private float _S_W_B_Wirefeedingspeed;
        public float S_W_B_Wirefeedingspeed
        {
            get { return _S_W_B_Wirefeedingspeed; }
            set { _S_W_B_Wirefeedingspeed = value; }
        }
        #endregion


        // 初始化
        public thePLCWelderStatus(bool Initialize)
        {
            _H_W_Q_Start = false;
            _H_W_Q_RobotReady = false;
            _H_W_Q_GasCheck = false;
            _H_W_M_OperationMode = 0;
            _H_W_M_WorkModel = 0;

            _H_W_Q_ISHighfrequency = false;
            _H_W_Q_WeldingGunMode = false;
            _H_W_D_GivenCurrent = 0;
            _H_W_D_PreAirTime = 0;
            _H_W_D_DelayAirTime = 0;

            _H_W_B_ClimbingTime = 0;
            _H_W_B_SDecayTime = 0;
            _H_W_B_PulseFrequency = 0;
            _H_W_B_DutyCycle = 0;
            _H_W_D_PeakCurrent = 0;

            _H_W_D_BaseCurrent = 0;
            _H_W_D_ArcingCurrent = 0;
            _H_W_D_ArcCurrent = 0;
            _H_W_B_CommunicationFrequency = 0;
            _H_W_B_CleaningRatio = 0;

            _H_W_B_ACOffset = 0;
            _H_R_I_CommunicationStatus = false;
            _H_R_I_ArcIgnitionSuccessful = false;
            _H_R_I_ISWeldingMachineReady = false;
            _H_R_I_ISCurrent = false;

            _H_R_I_AbnormalWeldingGunSwitch = false;
            _H_R_I_WeldingMachineThermalProtection = false;
            _H_R_I_WaterShortageProtection = false;
            _H_R_D_ActualWeldingVoltage = 0;
            _H_R_D_ActualWeldingCurrent = 0;

            _R_W_Q_HotWirePower = false;
            _R_W_Q_HotWireWorkMode = false;
            _R_W_B_HotWireFrequency = 0;
            _R_W_B_HotWireCurrent = 0;
            _H_R_I_HotWirePowerThermalProtection = false;

            _H_R_I_HotWirePowerCommunicationProtection = false;
            _R_R_D_HotWirecurrent = 0;

            _S_W_Q_WireFeedingJog = false;
            _S_W_Q_WirePullingJog = false;
            _S_W_B_Wirefeedingspeed = 0;

            _S_W_B_ArcInitiationDelayWireFeedingTime = 0;
            _S_W_B_ArcExtinguishingDelayWireFeedingTime = 0;
            _S_W_B_ArcExtinguishingAndRetractionlength = 0;
            _S_W_B_JoggingWireFeedingSpeed = 0;
            _S_W_B_SlowWireFeedingSpeed = 0;

            _S_R_D_WireFeedingSpeed = 0;
        }

    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct thePLCWelderSelect
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
        public bool[] select;
        public thePLCWelderSelect(bool Initialize)
        {
            select = new bool[GlobalVariables.WelderNum];
            for (int i = 0; i < GlobalVariables.WelderNum; i++)
            {
                select[i] = false;
            }
        }
    }


    /// <summary>
    /// 总焊机状态数据传递结构体
    /// </summary>
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct ALL_PLCWelderStatus
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]  // 这个地方要跟上面焊机总量相同
        public thePLCWelderStatus[] Axis;

        public ALL_PLCWelderStatus(bool Initialize)
        {
            Axis = new thePLCWelderStatus[GlobalVariables.WelderNum];
            for (int i = 0; i < GlobalVariables.WelderNum; i++)
            {
                Axis[i] = new thePLCWelderStatus(true);
            }
        }
    }



    /// <summary>
    /// 焊机基类，上位机用的数据类，对ITheWelder有另一层封装
    /// </summary>
    public class TheWelderBase : ITheWelder
    {
        /// <summary>
        /// 静态构造函数，初始化结构体属性，节约运行时间方便后续调用
        /// </summary>
        public static readonly PropertyInfo[] structProperties;

        /// <summary>
        /// 
        /// </summary>
        public static readonly PropertyInfo[] baseProperties;

        /// <summary>
        /// 静态构造函数
        /// </summary>
        static TheWelderBase()
        {
            structProperties = typeof(thePLCWelderStatus).GetProperties();
            baseProperties = typeof(TheWelderBase).GetProperties();
        }

        /// <summary>
        /// 每个焊机的独立编号，用于区分不同类的焊机，抽象类中初始化为0，实例化时每次都需要更新
        /// </summary>
        protected int WelderID { get; set; } = -1;

        /// <summary>
        /// 获取焊机编号
        /// </summary>
        public int GetWelderID { get { return WelderID; } }
        /// <summary>
        /// 焊机名称
        /// </summary>
        protected string welderName = "普通焊机";
        /// <summary>
        /// 获取焊机名称
        /// </summary>
        public string WelderName { get { return welderName; } }




        // 状态变量，Get环节
        #region 焊机

        public bool H_W_Q_Start { get; protected set; } = false;

        public bool H_W_Q_RobotReady { get; protected set; } = false;

        public bool H_W_Q_GasCheck { get; protected set; } = false;

        private short _H_W_M_OperationMode = 0;
        public short H_W_M_OperationMode
        {
            get { return _H_W_M_OperationMode; }
            set { _H_W_M_OperationMode = value; ChangeOperationMode(H_W_M_OperationMode); }
        }

        private short _H_W_M_WorkModel;
        public short H_W_M_WorkModel
        {
            get
            {
                return _H_W_M_WorkModel;
            }
            set
            {
                _H_W_M_WorkModel = value;
                ChangeWorkModel(H_W_M_WorkModel);
            }
        }

        public bool H_W_Q_ISHighfrequency { get; protected set; } = false;

        public bool H_W_Q_WeldingGunMode { get; protected set; } = false;

        public ushort H_W_D_GivenCurrent { get; protected set; } = 0;

        public float H_W_D_PreAirTime { get; protected set; } = 0;

        public float H_W_D_DelayAirTime { get; protected set; } = 0;

        public float H_W_B_ClimbingTime { get; protected set; } = 0;

        public float H_W_B_SDecayTime { get; protected set; } = 0;

        public float H_W_B_PulseFrequency { get; protected set; } = 0;

        public byte H_W_B_DutyCycle { get; set; } = 0;

        public ushort H_W_D_PeakCurrent { get; set; } = 0;

        public ushort H_W_D_BaseCurrent { get; set; } = 0;

        public ushort H_W_D_ArcingCurrent { get; set; } = 0;

        public ushort H_W_D_ArcCurrent { get; set; } = 0;

        public byte H_W_B_CommunicationFrequency { get; set; } = 0;

        public byte H_W_B_CleaningRatio { get; set; } = 0;

        public byte H_W_B_ACOffset { get; set; } = 0;


        // 读取部分
        public bool H_R_I_CommunicationStatus { get; protected set; } = false;

        public bool H_R_I_ArcIgnitionSuccessful { get; protected set; } = false;

        public bool H_R_I_ISWeldingMachineReady { get; protected set; } = false;

        public bool H_R_I_ISCurrent { get; protected set; } = false;

        public bool H_R_I_AbnormalWeldingGunSwitch { get; protected set; } = false;

        public bool H_R_I_WeldingMachineThermalProtection { get; protected set; } = false;

        public bool H_R_I_WaterShortageProtection { get; protected set; } = false;

        public ushort H_R_D_ActualWeldingVoltage { get; protected set; } = 0;

        public ushort H_R_D_ActualWeldingCurrent { get; protected set; } = 0;

        #endregion



        #region 热丝机


        public bool R_W_Q_HotWirePower { get; protected set; } = false;

        public bool R_W_Q_HotWireWorkMode { get; protected set; } = false;

        public byte R_W_B_HotWireFrequency { get; set; } = 0;

        public byte R_W_B_HotWireCurrent { get; protected set; } = 0;

        public bool H_R_I_HotWirePowerThermalProtection { get; protected set; } = false;

        public bool H_R_I_HotWirePowerCommunicationProtection { get; protected set; } = false;

        public ushort R_R_D_HotWirecurrent { get; set; } = 0;
        #endregion


        // 送丝机
        #region 送丝机

        public bool S_W_Q_WireFeedingJog { get; protected set; } = false;

        public bool S_W_Q_WirePullingJog { get; protected set; } = false;

        public float S_R_D_WireFeedingSpeed { get; set; } = 0;

        public float S_W_B_ArcInitiationDelayWireFeedingTime { get; set; } = 0;

        public float S_W_B_ArcExtinguishingDelayWireFeedingTime { get; set; } = 0;

        public byte S_W_B_ArcExtinguishingAndRetractionlength { get; set; } = 0;

        public float S_W_B_JoggingWireFeedingSpeed { get; set; } = 0;

        public float S_W_B_SlowWireFeedingSpeed { get; set; } = 0;

        public float S_W_B_Wirefeedingspeed { get; protected set; } = 0;

        #endregion

        

        /// <summary>
        /// 输入结构体数据并更新当前类的属性
        /// </summary>
        /// <param name="structure"></param>
        public void UpdateStructureValues(thePLCWelderStatus structure)
        {
            foreach (var property in structProperties)
            {
                var classProperty = this.GetType().GetProperty(property.Name);
                if (classProperty != null && classProperty.CanWrite)
                {
                    classProperty.SetValue(this, property.GetValue(structure), null);
                }
            }
        }

        /// <summary>
        /// 复制当前类的属性值到新的结构体
        /// </summary>
        /// <returns>向下位机发送信息包的structure</returns>
        public thePLCWelderStatus CopyClassValues(thePLCWelderStatus structure)
        {
            object boxedStructure = structure;
            foreach (var property in structProperties)
            {
                // structProperties是structure的属性列表，property是其中一个属性
                var classProperty = this.GetType().GetProperty(property.Name);  
                // 这里是class的属性，而不是structure的属性
                // 用到了this.GetType()，表示当前类的类型，如果在外面类中调用的话，还是需要base的反射表的

                // var structureProperty = structure.GetType().GetProperty(property.Name);
                if (classProperty != null && classProperty.CanWrite)
                {
                    var value = classProperty.GetValue(this, null);  // 值能够正常拿出
                    // 这个值来自class，要写入structure

                    // Console.WriteLine(value.GetType() != structureProperty.PropertyType);

                    // 指定实例是否可以分配给当前实例
                    // Console.WriteLine(!structureProperty.PropertyType.IsAssignableFrom(value.GetType()));
                    if (value != null && !property.PropertyType.IsAssignableFrom(value.GetType()))
                    {
                        value = Convert.ChangeType(value, property.PropertyType);
                    }

                    property.SetValue(boxedStructure, value, null); // 改对了之后还涉及到结构体装箱拆箱的问题，结构体不能直接返回修改
                    // 因为是一个值类型，不是引用类型，所以需要拆箱装箱


                    // structureProperty.PropertyType.IsGenericType 这一项是false，表明类型是基类，不是泛型
                }
            }
            return (thePLCWelderStatus)boxedStructure;
        }

        /// <summary>
        /// 焊机工作模式显示字符串：0关机 1直流恒流   2直流脉冲  3交流恒流  4交流脉冲  5直流手弧焊
        /// </summary>
        public string WelderWorkModel { get; private set; } = "关机";

        /// <summary>
        /// 根据H_W_M_WorkModel的值改变WelderWorkModel的值
        /// </summary>
        /// <param name="H_W_M_WorkModel"></param>
        private void ChangeWorkModel(short H_W_M_WorkModel)
        {
            
            switch (H_W_M_WorkModel)
            {
                case 0:
                    WelderWorkModel = "关机";
                    break;
                case 1:
                    WelderWorkModel = "直流恒流";
                    break;
                case 2:
                    WelderWorkModel = "直流脉冲";
                    break;
                case 3:
                    WelderWorkModel = "交流恒流";
                    break;
                case 4:
                    WelderWorkModel = "交流脉冲";
                    break;
                case 5:
                    WelderWorkModel = "直流手弧焊";
                    break;
                default:
                    break;
            }

        }


        public string WelderOperationMode { get; private set; } = "关机";
        /// <summary>
        /// 根据H_W_M_OperationMode的值改变WelderOperationMode的值
        /// </summary>
        /// <param name="H_W_M_OperationMode"></param>
        private void ChangeOperationMode(short H_W_M_OperationMode)
        {
            switch (H_W_M_OperationMode)
            {
                case 0:
                    WelderOperationMode = "关机";
                    break;
                case 1:
                    WelderOperationMode = "两步";
                    break;
                case 2:
                    WelderOperationMode = "四步";
                    break;
                case 3:
                    WelderOperationMode = "反复";
                    break;
                default:
                    break;
            }
        }

    }

    /// <summary>
    /// 独立的焊机类，继承TheWelderBase
    /// </summary>
    public class TheSeparateWelder : TheWelderBase
    {
        // 独立焊机编号,静态构造函数，这是类级别的方法，属于类而不是实例变量
        public TheSeparateWelder()
        {
            WelderID = 0;
            welderName = "独立焊机";
        }
    }

    /// <summary>
    /// 固定的焊机类，继承TheWelderBase
    /// </summary>
    public class TheConcentratedWelder : TheWelderBase
    {

        public TheConcentratedWelder()
        {
            WelderID = 1; // 固定焊机编号
            welderName = "固定焊机";
        }


    }
    /// <summary>
    /// 焊机写入数据的存放类，使用这个类向PLC写入数据
    /// </summary>
    public class NewWelders : TheWelderBase
    {

    }

    /// <summary>
    /// 整体的焊机类，包含焊机的各种检查变量
    /// </summary>
    public class TheWelders
    {
        #region 焊机系统状态监测变量

        //按钮打开标志  // 这是七个大检查目标，用静态参数表示

        /// <summary>
        /// 送丝开关变量
        /// </summary>
        public bool SongsiEnableStatus { get; protected set; } = false;

        /// <summary>
        /// 热丝开关变量
        /// </summary>
        public bool ResiStartStatus { get; protected set; } = false;

        /// <summary>
        /// 气检变量
        /// </summary>
        public bool GasCheckStatus { get; protected set; } = false;

        /// <summary>
        /// 起弧变量
        /// </summary>
        public bool AstartStatus { get; protected set; } = false;


        // 焊机状态变量
        /// <summary>
        /// 焊机状态变量
        /// </summary>
        public bool WelderStatus { get; protected set; } = false;

        /// <summary>
        /// 热丝机状态变量
        /// </summary>
        public bool resiReadyStatus { get; protected set; } = false;

        /// <summary>
        /// 送丝机状态变量
        /// </summary>
        public bool songsiStartStatus { get; protected set; } = false;

        #endregion

        // TODO：焊机状态检测，来控制按钮开关


        #region ads客户端通信读取数据

        /// <summary>
        /// 主机ADSnetID
        /// </summary>
        public string AMSNETID { get; set; } = "127.0.0.1.1.1";
        // plc地址
        // 169.254.99.100.1.1
        // 127.0.0.1.1.1

        /// <summary>
        /// ADS客户端连接端口号
        /// </summary>
        public int Port { get; set; } = 851;

        /// <summary>
        /// ADS客户端实例化
        /// </summary>
        public TcAdsClient AdsClient { get; protected set; }

        /// <summary>
        /// ADS客户端事件触发通知句柄
        /// </summary>
        private ArrayList notificationHandles;

        /// <summary>
        /// 下位机焊机状态参数的int句柄
        /// 下位机读取的变量名称 GVL_Welders.Welders
        /// </summary>
        private int Int_AllPlcWelderStatus = 0;

        /// <summary>
        /// 下位机焊机选中焊机的int句柄
        /// 下位机读取的变量名称 GVL_flag.Flag_Sel
        /// </summary>
        private int Int_PLCSelect = 0;

        /// <summary>
        /// 获取所有焊机状态，只用来读焊机的数据
        /// </summary>
        public ALL_PLCWelderStatus AllPlcWelderStatus = new ALL_PLCWelderStatus(true);

        /// <summary>
        /// 选中焊机
        /// </summary>
        public thePLCWelderSelect PLCSelect = new thePLCWelderSelect(true);

        /// <summary>
        /// 定时循环读取所有焊机状态
        /// </summary>
        public bool TimeTickerStart { get; set; } = false;

        /// <summary>
        /// 连接ADS客户端
        /// </summary>
        public void Connect()
        {
            AdsClient = new TcAdsClient();
            notificationHandles = new ArrayList();
            try
            {
                AdsClient.AdsNotificationEx += new AdsNotificationExEventHandler(adsClient_AdsNotification);

                AdsClient.Connect(AMSNETID, Port);  // 一个字符地址，一个数字端口

                Int_AllPlcWelderStatus = AdsClient.CreateVariableHandle("GVL_Welders.Welders");

                Int_PLCSelect = AdsClient.CreateVariableHandle("GVL_flag.Flag_Sel");
            }
            catch (Exception ex)
            {
                throw new Exception("连接失败，请检查PLC是否启动。" + ex.Message);
            }
        }

        /// <summary>
        /// 断开ADS客户端
        /// </summary>
        public void Disconnect()

        {
            AdsClient.Dispose();
        }




        #region 开放的ADS客户端事件，方便被外界调用

        /// <summary>
        /// 下位机数据改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void adsClient_AdsNotification(object sender, AdsNotificationExEventArgs e)
        {
            //TODO: 下位机值改变事件信息处理
        }


        /// <summary>
        /// 一次性添加所有监控的下位机数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddNotification(object sender, EventArgs e)
        {
            //TODO: 添加通知
        }

        /// <summary>
        /// 删除所有监控的下位机数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void DeleteNotification(object sender, EventArgs e)
        {
            try
            {
                foreach (var item in notificationHandles)
                {
                    AdsClient.DeleteDeviceNotification((int)item);
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show("删除通知失败。" + ex.Message);
            }
            notificationHandles.Clear();
        }


        /// <summary>
        /// 选中焊机状态更新
        /// </summary>
        public void PLCWriteSelect(List<bool> theSelectedWeldersIndex)
        {
            for (int i = 0; i < theSelectedWeldersIndex.Count; i++)
            {
                PLCSelect.select[i] = theSelectedWeldersIndex[i];
            }
            try
            {
                if (AdsClient != null && AdsClient.IsConnected)
                {
                    AdsClient.WriteAny(Int_PLCSelect, PLCSelect.select);
                }
                else
                {
                    throw new Exception("连接失败，请检查PLC是否启动。");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("焊机索引写入失败。" + ex.Message);
            }
        }


        /// <summary>
        /// 用结构体向下位机写入数据
        /// </summary>
        /// <param name="allTheWelders">需要写入的焊机数组数据</param>
        public void WriteValues(List<TheWelderBase> allTheWelders)
        {
            ALL_PLCWelderStatus sendValueStruct = new ALL_PLCWelderStatus(true);
            for (int i = 0; i < GlobalVariables.WelderNum; i++)
            {
                sendValueStruct.Axis[i] = allTheWelders[i].CopyClassValues(sendValueStruct.Axis[i]); // 这一部分数据被传入了
            }
            try
            {
                AdsClient.WriteAny(Int_AllPlcWelderStatus, sendValueStruct);
            }
            catch(Exception ex)
            {
                throw new Exception("写入数据失败。" + ex.Message);
            }
        }


        /// <summary>
        /// 从下位机读取数据
        /// </summary>
        public void ReadValues()
        {
            try
            { 
                AllPlcWelderStatus = (ALL_PLCWelderStatus)AdsClient.ReadAny(Int_AllPlcWelderStatus, typeof(ALL_PLCWelderStatus));
            }
            catch (Exception ex)
            {
                throw new Exception("读取数据失败。" + ex.Message);
            }
        }




        #endregion



        #endregion


        // 进行优化，使用类的多态来简化方法，不需要强制分为两类了

        /// <summary>
        /// 所有焊机的动态数组，使用多态来简化处理
        /// </summary>
        private List<TheWelderBase> allTheWelders = new List<TheWelderBase>();

        #region 对整个焊机系统进行操作
        /// <summary>
        /// 增加焊机数量
        /// </summary>
        public void AddWelders(int WelderID = 0)
        {
            TheSeparateWelder welder1 = new TheSeparateWelder();
            TheConcentratedWelder welder2 = new TheConcentratedWelder();   // 先创建俩，再看谁不用就丢掉

            if (WelderID == welder1.GetWelderID)   // 这地方应该是用静态方法，因为脱离类存在
            {
                allTheWelders.Add(welder1);
            }
            else if (WelderID == welder2.GetWelderID)
            {
                allTheWelders.Add(welder2);
            }
            else
            {
                throw new Exception("不存在此类焊机"); // 抛出异常
            }
        }
        /// <summary>
        /// 删除焊机数量，默认删除每类最后一个焊机，之后如果有需求，可以修改
        /// 此外，在焊机类中，默认将独立焊机索引放在前面，集中焊机放在后面
        /// </summary>
        public void RemoveWelders(int WelderID = 0)
        {
            try
            {
                // 保证已经先创建了焊机，才能有对应的最后一个焊机的删除
                if ((allTheWelders.Count > 0) && (WelderID == allTheWelders[GlobalVariables.SeparateWelderNum - 1].GetWelderID))
                {
                    allTheWelders.RemoveAt(GlobalVariables.SeparateWelderNum - 1);
                }
                else if ((allTheWelders.Count > 0) && (WelderID == allTheWelders[GlobalVariables.ConcentratedWelderNum - 1].GetWelderID))
                {
                    allTheWelders.RemoveAt(GlobalVariables.ConcentratedWelderNum - 1);
                }
                else
                {
                    throw new Exception("焊机列表为空无法删除"); // 抛出异常
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("焊机列表为空无法删除");
            }
        }

        /// <summary>
        /// 清空焊机列表，删除所有焊机，初始化使用
        /// </summary>
        public void ClearWelders()
        {
            if (allTheWelders.Count > 0)
            {
                allTheWelders.Clear();
            }
            
        }


        /// <summary>
        /// 获取下位机所有焊机信息，包括独立焊机和集中焊机
        /// </summary>
        /// <returns></returns>
        public List<TheWelderBase> GetWelderInformation()
        {
            return allTheWelders; // 返回数组，这种方式返回的数组不用了会删除么？
        }

        private void InitializeWelders()
        {
            // 存入数据
            for (int i = 0; i < GlobalVariables.SeparateWelderNum; i++)
            {
                AddWelders(0);
            }
            for (int i = 0; i < GlobalVariables.ConcentratedWelderNum; i++)
            {
                AddWelders(1);
            }
        }

        #region 获取各类焊机数量的方法
        /// <summary>
        /// 获取所有焊机数量，返回一个int值
        /// </summary>
        /// <returns></returns>
        public int GetWelderCount()
        { return GlobalVariables.WelderNum; }
        /// <summary>
        /// 获取所有独立焊机数量，返回一个int值
        /// </summary>
        /// <returns></returns>
        public int GetSeparateWelderCount()
        { return GlobalVariables.SeparateWelderNum; }
        /// <summary>
        /// 获取所有集中焊机数量，返回一个int值
        /// </summary>
        /// <returns></returns>
        public int GetConcentratedWelderCount()
        { return GlobalVariables.ConcentratedWelderNum; }
        #endregion

        #endregion  

        /// <summary>
        /// 构造器
        /// </summary>
        public TheWelders()
        {
            ClearWelders();  // 数组初始化
            InitializeWelders();
        }

    }
}
